using UnityEngine;

namespace FreeDraw
{
	[RequireComponent(typeof(SpriteRenderer))]
	[RequireComponent(typeof(Collider2D))]
	public class Drawable : MonoBehaviour
	{
		public delegate void Brush_Function(Vector2 world_position);

		public static Color Pen_Colour = Color.red;

		public static int Pen_Width = 10;

		public Brush_Function current_brush;

		public LayerMask Drawing_Layers;

		public bool Reset_Canvas_On_Play = true;

		public Color Reset_Colour = new Color(0f, 0f, 0f, 0f);

		public static Drawable drawable;

		private Sprite drawable_sprite;

		private Texture2D drawable_texture;

		private Vector2 previous_drag_position;

		private Color[] clean_colours_array;

		private Color transparent;

		private Color32[] cur_colors;

		private bool mouse_was_previously_held_down;

		private bool no_drawing_on_current_drag;

		public void BrushTemplate(Vector2 world_position)
		{
			Vector2 vector = WorldToPixelCoordinates(world_position);
			cur_colors = drawable_texture.GetPixels32();
			if (previous_drag_position == Vector2.zero)
			{
				MarkPixelsToColour(vector, Pen_Width, Pen_Colour);
			}
			else
			{
				ColourBetween(previous_drag_position, vector, Pen_Width, Pen_Colour);
			}
			ApplyMarkedPixelChanges();
			previous_drag_position = vector;
		}

		public void PenBrush(Vector2 world_point)
		{
			Vector2 vector = WorldToPixelCoordinates(world_point);
			Vector2 center_pixel = vector;
			cur_colors = drawable_texture.GetPixels32();
			if (previous_drag_position == Vector2.zero)
			{
				MarkPixelsToColour(center_pixel, Pen_Width, Pen_Colour);
			}
			else
			{
				ColourBetween(previous_drag_position, vector, Pen_Width, Pen_Colour);
			}
			ApplyMarkedPixelChanges();
			previous_drag_position = center_pixel;
		}

		public void SetPenBrush()
		{
			current_brush = PenBrush;
		}

		private void Update()
		{
			bool mouseButton = Input.GetMouseButton(0);
			if (mouseButton && !no_drawing_on_current_drag)
			{
				Vector2 vector = Camera.main.ScreenToWorldPoint(Input.mousePosition);
				Collider2D collider2D = Physics2D.OverlapPoint(vector, Drawing_Layers.value);
				if (collider2D != null && collider2D.transform != null)
				{
					current_brush(vector);
				}
				else
				{
					previous_drag_position = Vector2.zero;
					if (!mouse_was_previously_held_down)
					{
						no_drawing_on_current_drag = true;
					}
				}
			}
			else if (!mouseButton)
			{
				previous_drag_position = Vector2.zero;
				no_drawing_on_current_drag = false;
			}
			mouse_was_previously_held_down = mouseButton;
		}

		public void ColourBetween(Vector2 start_point, Vector2 end_point, int width, Color color)
		{
			float num = Vector2.Distance(start_point, end_point);
			_ = (start_point - end_point).normalized;
			Vector2 vector = start_point;
			float num2 = 1f / num;
			for (float num3 = 0f; num3 <= 1f; num3 += num2)
			{
				vector = Vector2.Lerp(start_point, end_point, num3);
				MarkPixelsToColour(vector, width, color);
			}
		}

		public void MarkPixelsToColour(Vector2 center_pixel, int pen_thickness, Color color_of_pen)
		{
			int num = (int)center_pixel.x;
			int num2 = (int)center_pixel.y;
			for (int i = num - pen_thickness; i <= num + pen_thickness; i++)
			{
				if (i < (int)drawable_sprite.rect.width && i >= 0)
				{
					for (int j = num2 - pen_thickness; j <= num2 + pen_thickness; j++)
					{
						MarkPixelToChange(i, j, color_of_pen);
					}
				}
			}
		}

		public void MarkPixelToChange(int x, int y, Color color)
		{
			int num = y * (int)drawable_sprite.rect.width + x;
			if (num <= cur_colors.Length && num >= 0)
			{
				cur_colors[num] = color;
			}
		}

		public void ApplyMarkedPixelChanges()
		{
			drawable_texture.SetPixels32(cur_colors);
			drawable_texture.Apply();
		}

		public void ColourPixels(Vector2 center_pixel, int pen_thickness, Color color_of_pen)
		{
			int num = (int)center_pixel.x;
			int num2 = (int)center_pixel.y;
			for (int i = num - pen_thickness; i <= num + pen_thickness; i++)
			{
				for (int j = num2 - pen_thickness; j <= num2 + pen_thickness; j++)
				{
					drawable_texture.SetPixel(i, j, color_of_pen);
				}
			}
			drawable_texture.Apply();
		}

		public Vector2 WorldToPixelCoordinates(Vector2 world_position)
		{
			Vector3 vector = base.transform.InverseTransformPoint(world_position);
			Vector3 vector2 = new Vector3(vector.x / base.transform.localScale.x, vector.y / base.transform.localScale.y, vector.z / base.transform.localScale.z);
			float width = drawable_sprite.rect.width;
			float height = drawable_sprite.rect.height;
			float num = width / drawable_sprite.bounds.size.x * base.transform.localScale.x;
			float f = vector2.x * num + width / 2f;
			float f2 = vector2.y * num + height / 2f;
			return new Vector2(Mathf.RoundToInt(f), Mathf.RoundToInt(f2));
		}

		public void ResetCanvas()
		{
			drawable_texture.SetPixels(clean_colours_array);
			drawable_texture.Apply();
		}

		private void Awake()
		{
			drawable = this;
			current_brush = PenBrush;
			drawable_sprite = GetComponent<SpriteRenderer>().sprite;
			drawable_texture = drawable_sprite.texture;
			clean_colours_array = new Color[(int)drawable_sprite.rect.width * (int)drawable_sprite.rect.height];
			for (int i = 0; i < clean_colours_array.Length; i++)
			{
				clean_colours_array[i] = Reset_Colour;
			}
			if (Reset_Canvas_On_Play)
			{
				ResetCanvas();
			}
		}
	}
}
